package cn.yuanqiao.archive.chengguojieshou.service.impl;

import cn.yuanqiao.archive.appManager.domain.*;
import cn.yuanqiao.archive.appManager.mapper.TenantCodeListMapper;
import cn.yuanqiao.archive.appManager.mapper.TenantYqdaDocumentMapper;
import cn.yuanqiao.archive.appManager.mapper.TenantYqdaMapper;
import cn.yuanqiao.archive.appManager.service.ITenantCategoryService;
import cn.yuanqiao.archive.appManager.service.ITenantCoderuleService;
import cn.yuanqiao.archive.appManager.service.ITenantSysConfigService;
import cn.yuanqiao.archive.chengguojieshou.domain.ArticulateCount;
import cn.yuanqiao.archive.chengguojieshou.domain.Yqdaarticulated;
import cn.yuanqiao.archive.chengguojieshou.domain.YqdaarticulatedLog;
import cn.yuanqiao.archive.chengguojieshou.domain.YqdaarticulatedServerLog;
import cn.yuanqiao.archive.chengguojieshou.mapper.YqdaarticulatedMapper;
import cn.yuanqiao.archive.chengguojieshou.service.IYqdaarticulatedService;
import cn.yuanqiao.archive.webservice.utils.WebServiceFileUtils;
import cn.yuanqiao.archive.wenjianzhengli.utils.FileUploadUtils;

import cn.yuanqiao.common.enums.DbIdEnum;
import cn.yuanqiao.common.exception.ServiceException;
import cn.yuanqiao.common.utils.*;
import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.io.FileUtils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * 挂接Service业务层处理
 *
 * @author yuanqiao
 * @date 2023-06-30
 */
@Service
public class YqdaarticulatedServiceImpl implements IYqdaarticulatedService
{
    @Autowired
    private YqdaarticulatedMapper yqdaarticulatedMapper;
    @Autowired
    private ITenantCoderuleService tenantCoderuleService;
    @Autowired
    private ITenantCategoryService tenantCategoryService;
    @Autowired
    private TenantCodeListMapper tenantCodeListMapper;
    @Autowired
    private TenantYqdaDocumentMapper documentMapper;
    @Autowired
    private TenantYqdaMapper yqdaMapper;
    @Autowired
    private ITenantSysConfigService sysConfigService;
    @Resource
    private SqlSessionFactory sqlSessionFactory;
    @Value("${FBswitch}")
    private Boolean FBswitch;

    private DateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private static final Logger logger = LoggerFactory.getLogger(YqdaarticulatedServiceImpl.class);

    private Map<Long, ArticulateCount> countMap = new ConcurrentHashMap<>();

    /**
     * 查询挂接
     *
     * @param ID 挂接主键
     * @return 挂接
     */
    @Override
    public Yqdaarticulated selectBjyqYqdaarticulatedByID(String ID)
    {
        return yqdaarticulatedMapper.selectBjyqYqdaarticulatedByID(ID);
    }

    /**
     * 查询挂接列表
     *
     * @param bjyqYqdaarticulated 挂接
     * @return 挂接
     */
    @Override
    public List<Yqdaarticulated> selectBjyqYqdaarticulatedList(Yqdaarticulated bjyqYqdaarticulated)
    {
        bjyqYqdaarticulated.setCreateBy(SecurityUtils.getUsername());
        bjyqYqdaarticulated.setSTATE("1");
        return yqdaarticulatedMapper.selectBjyqYqdaarticulatedList(bjyqYqdaarticulated);
    }
    @Override
    public List<Yqdaarticulated> serverList(Yqdaarticulated bjyqYqdaarticulated)
    {
        bjyqYqdaarticulated.setCreateBy(SecurityUtils.getUsername());
        bjyqYqdaarticulated.setSTATE("2");
        return yqdaarticulatedMapper.selectBjyqYqdaarticulatedList(bjyqYqdaarticulated);
    }

    @Override
    public List<YqdaarticulatedLog> getArticulatedLog(String id)
    {
        YqdaarticulatedLog yqdaarticulatedLog = new YqdaarticulatedLog();
        return yqdaarticulatedMapper.getArticulatedLog(Long.valueOf(id),yqdaarticulatedLog.getTableName());
    }
    @Override
    public List<YqdaarticulatedServerLog> getServerLogList(String id)
    {
        YqdaarticulatedServerLog yqdaarticulatedLog = new YqdaarticulatedServerLog();
        return yqdaarticulatedMapper.getServerLogList(Long.valueOf(id),yqdaarticulatedLog.getTableName());
    }


    @Override
    public List<Map<String, Object>> getNotarticulatedList(Long categoryId,Integer type) {  //type  0：档案接收 1：档案管理
        String state = "2,3,4,5";
        if(null!=type){
            if(type==1){
                state = "5";
            } else if(type==0){
                state = "3,11,12";
            }else if(type == 2){
                state = "12";
            }
        }
        TenantCodeRule codeRule = new TenantCodeRule();
        Yqdaarticulated yqdaarticulated = new Yqdaarticulated();
        codeRule.setCategoryModelId(categoryId);
        TenantCategory tenantCategory = tenantCategoryService.selectTenanCategoryByID(categoryId);
        String fileTableName = tenantCategory.getFileTableName();
        String efileTableName = tenantCategory.getEfileTableName();
        List<TenantCodeRule> tenantCodeRules = tenantCoderuleService.selectYqdaCoderuleModelList(codeRule);
        List<Map<String,Object>> list = new ArrayList<>();
        String sentence = " and trim(a.DH) != ''  ";
        String dataBaseId = sqlSessionFactory.getConfiguration().getDatabaseId();
        if(dataBaseId.equalsIgnoreCase(DbIdEnum.KINGBASE.getCode())){
            sentence = " and a.DH is not null ";
        }
        //拼接sql
        String sql = "";
        if(tenantCodeRules.size()>0){
            sql+="SELECT ID,DH,QZH,TITLE,BGQX,STATE FROM (";
            for(int i=0;i<tenantCodeRules.size();i++){
                TenantCodeRule next = tenantCodeRules.get(i);
                if(i == tenantCodeRules.size()-1){
                    String notarticulatedSql = getNotarticulatedSql(next, categoryId, tenantCategory, yqdaarticulated,state);
                    sql+=notarticulatedSql;
                }else{
                    String notarticulatedSql = getNotarticulatedSql(next, categoryId, tenantCategory, yqdaarticulated,state);
                    sql+=notarticulatedSql + " UNION ALL ";
                }
            }
            sql +=") a";
        }else{
            String currDate = DateUtils.dateTimeNow8();
            sql+="select ID,DH,QZH,TITLE,BGQX,STATE " +
                    "from "+fileTableName+" a " +
                        "where a.is_del = 0 and a.state in ("+state+") "+sentence+" and  " +
                    "not exists (SELECT d.CON_TABLE_ID as id FROM "+yqdaarticulated.getTableName()+" r " +
                    "left join "+efileTableName+" d on r.ID = d.ARTICULATED_ID where r.CATEGORY_ID = "+categoryId+" and a.id = " +
                    "d.con_table_id )";
        }
        PageUtils.startPage();
        list = yqdaarticulatedMapper.executeSql(sql);
        return list;
    }

    public String getNotarticulatedSql(TenantCodeRule rule, Long categoryId, TenantCategory tenantCategory,
                                       Yqdaarticulated yqdaarticulated, String state){
        String fColumnname = rule.getfColumnname();
        //Integer starttime = rule.getStarttime();
        //Integer endtime = rule.getEndtime();
        String fileTableName = tenantCategory.getFileTableName();
        String efileTableName = tenantCategory.getEfileTableName();
        String sentence = " and trim(a."+fColumnname+") != '' ";
        String dataBaseId = sqlSessionFactory.getConfiguration().getDatabaseId();
        if(dataBaseId.equalsIgnoreCase(DbIdEnum.KINGBASE.getCode())){
            sentence = " and a."+fColumnname+" is not null ";
        }
                String sql="select ID,"+fColumnname+",QZH,TITLE,BGQX,STATE " +
                "from "+fileTableName+" a " +
                "where a.is_del = 0 and a.state in ("+state+") "+sentence+" and " +
                "not exists (SELECT d.CON_TABLE_ID as id FROM "+yqdaarticulated.getTableName()+" r " +
                "left join "+efileTableName+" d on r.ID = d.ARTICULATED_ID where r.CATEGORY_ID = "+categoryId+" and a.id = " +
                "d.con_table_id ) ";
        return sql;
    }

    @Override
    public Map<String, Object> articulated(JSONObject json) {
        String uplodPath = sysConfigService.selectConfigByKey("YQ_MNT");
        String repateOperationMode = json.getString("repateOperationMode");
        String fielNumberField = json.getString("fielNumberField");
        String archivalCodeDefine = json.getString("archivalCodeDefine");
        String fileType = json.getString("fileType");
        String gjfs = json.getString("GJFS");
        String unZipPath = json.getString("unZipPath");   //解压后的文件夹路径
        String categoryId = json.getString("categoryId");
        String articulatedType = json.getString("articulatedType");
        String typeState = json.getString("typeState");
        if(!StringUtils.isNotEmpty(repateOperationMode)) {
            if(!"server".equals(articulatedType)){
                throw new ServiceException("重复数据校验方式不能为空");
            }else{
                throw new ServiceException("重复策略不能为空");
            }
        }
        if(!StringUtils.isNotEmpty(fielNumberField)) {
            if(!"server".equals(articulatedType)){
                throw new ServiceException("档号字段不能为空");
            }else{
                throw new ServiceException("匹配策略不能为空");
            }
        }
        if(!StringUtils.isNotEmpty(categoryId)) throw new ServiceException("门类id不能为空");
        if(!"server".equals(articulatedType)){   //服务器挂接 不校验
            if(!StringUtils.isNotEmpty(archivalCodeDefine)) throw new ServiceException("档号定义不能为空");
        }

        long l = SnowflakeIdGenerator.generateId();
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("repateOperationMode",repateOperationMode);
        paramMap.put("fielNumberField",fielNumberField);
        paramMap.put("archivalCodeDefine",archivalCodeDefine);
        paramMap.put("fileType",fileType);
        paramMap.put("gjfs",gjfs);
        paramMap.put("categoryId",categoryId);
        paramMap.put("parentPath","");
        paramMap.put("uplodPath",uplodPath);
        paramMap.put("articulateId",String.valueOf(l));
        paramMap.put("articulatedType",articulatedType);
        paramMap.put("typeState",typeState);
        if("NAME_TYPE".equalsIgnoreCase(gjfs)){
            String tenantCode = SecurityUtils.getTenantCode();
            List<Map<String, Object>> maps = yqdaarticulatedMapper.executeSql("select REMARK,DICT_VALUE from " + tenantCode + "_DICT_DATA WHERE DICT_TYPE = 'TYPE'");
            String remarks = "";
            for(int j=0;j<maps.size();j++){
                Map<String, Object> k = maps.get(j);
                String remark = String.valueOf(k.get("REMARK"));
                String dict_value = String.valueOf(k.get("DICT_VALUE"));
                if(StringUtils.isNotEmpty(remark) && !"null".equals(remark)){
                    remarks+=remark+":"+dict_value+",";
                }
            }
            if(remarks.endsWith(",")) remarks = remarks.substring(0,remarks.length()-1);
            paramMap.put("remarks",remarks);
        }
        if("DH_TITLE".equalsIgnoreCase(gjfs)){

        }
        long id = Thread.currentThread().getId();
        ArticulateCount articulateCount = new ArticulateCount();
        countMap.put(id,articulateCount);

        //获取对应门类信息
        TenantCategory tenantCategory = tenantCategoryService.selectTenanCategoryByID(Long.valueOf(categoryId));
        File srcFile = new File(unZipPath);
        copyFiles(srcFile,paramMap,tenantCategory);

        Yqdaarticulated arti = new Yqdaarticulated();
        arti.setId(l);
        arti.setOperationMode(repateOperationMode);
        arti.setCategoryId(Long.valueOf(categoryId));
        if("server".equals(articulatedType)){
            //服务器挂接暂不添加批次号
            arti.setSTATE("2");  // 2 代表服务器挂接
            String results = "挂接：成功"+articulateCount.success+"条，失败"+articulateCount.fail+"条，跳过"+articulateCount.jump+"条，覆盖"+articulateCount.cover+"条";
            arti.setArticulatedResults(results);
        }else{
            Integer BatchNo = 0;
            Yqdaarticulated yqdaarticulated = new Yqdaarticulated();
            String maxBatchNo = yqdaarticulatedMapper.getMaxBatchNo(yqdaarticulated.getTableName());
            BatchNo = StringUtils.isNotEmpty(maxBatchNo)?Integer.parseInt(maxBatchNo)+1:1;

            arti.setBatchNo(BatchNo.toString());
            arti.setSTATE("1");   // 1 代表客户端挂接
            String results = "挂接：成功"+articulateCount.success+"条，失败"+articulateCount.fail+"条，跳过"+articulateCount.jump+"条，覆盖"+articulateCount.cover+"条，追加"+articulateCount.add+"条";
            arti.setArticulatedResults(results);
        }
        arti.setArticulatedTime(DateUtils.getTime());
        arti.setCreateBy(SecurityUtils.getUsername());
        int i = yqdaarticulatedMapper.insertBjyqYqdaarticulated(arti);
        if(!"server".equals(articulatedType)){
            File file = new File(unZipPath);
            if(file.exists() && file.isDirectory()){
                //删除解压后的文件夹
                FileUtils.deleteQuietly(file);
            }
        }
        countMap.remove(id);  //移除统计数据
        Map<String, Object> map = new HashMap<>();
        map.put("articulatedId",l);
        map.put("msg",i>0?"挂接完成":"挂接失败");
        return map;
    }

    public void copyFiles(File srcFile, Map<String,String> map, TenantCategory tenantCategory){
        String databaseId = sqlSessionFactory.getConfiguration().getDatabaseId();
        long id = Thread.currentThread().getId();
        ArticulateCount articulateCount = countMap.get(id);
        String ruleId = map.get("archivalCodeDefine");
        String parentPath = map.get("parentPath");
        String uplodPath = map.get("uplodPath");
        String fileType = map.get("fileType");  //1：正文 2：文稿 3：报批件 4：附件
        String fielNumberField = map.get("fielNumberField");
        String repateOperationMode = map.get("repateOperationMode");
        String articulateId = map.get("articulateId");
        String articulatedType = map.get("articulatedType");
        String typeState = map.get("typeState");
        if(srcFile.isDirectory()){
            File[] tmp = srcFile.listFiles();//取文件夹下是文件
            for (int i = 0; i < tmp.length; i++) {//循环文件
                map.put("parentPath", parentPath+tmp[i].getName()+",,,");
                copyFiles(tmp[i],map,tenantCategory);//递归调用
            }
        }else{
            String fileName = srcFile.getName();  //文件名
            String ext = fileName.substring(fileName.lastIndexOf(".")+1,fileName.length());
            String path = null;
            try {
                path = srcFile.getCanonicalPath();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try{
                String archivelCode = parentPath;   //路径拼接
                String dh = "";
                if("NAME".equalsIgnoreCase(map.get("gjfs"))){   //文件名挂接
                    dh=fileName.substring(0,fileName.lastIndexOf("."));
                }
                if("LEVEL".equalsIgnoreCase(map.get("gjfs"))){   //文件夹层级挂接
                    dh = getDHByLevel(tenantCategory,ruleId,archivelCode);
                }
                if("DIRECTORY_NAME".equalsIgnoreCase(map.get("gjfs"))){  //文件夹名称
                    dh = srcFile.getParentFile().getName();
                }
                if("NAME_TYPE".equalsIgnoreCase(map.get("gjfs"))){
                    String fileNameWithOutExt = fileName.substring(0, fileName.lastIndexOf("."));
                    String remarks = map.get("remarks");
                    if(!"".equals(remarks)){
                        String[] remarkSplit = remarks.split(",");
                        for(String suffix:remarkSplit){
                            String[] split = suffix.split(":");
                            if(fileNameWithOutExt.endsWith(split[0])){
                                int length = split[0].length();
                                fileType = split[1];
                                dh = fileNameWithOutExt.substring(0,fileNameWithOutExt.length()-length);
                                break;
                            }
                        }
                        if("".equals(dh)){
                            logger.error("文件类型备注配置有误。未找到档号");
                        }
                    }else{
                        throw new ServiceException("文件类型备注未配置");
                    }
                }
                if("DH_TITLE".equalsIgnoreCase(map.get("gjfs"))){
                    dh=fileName.split("_")[0];
                }
                //根据档号查询数据
                List<Map<String, Object>> maps = hasArchive(tenantCategory.getFileTableName(), fielNumberField, dh.replaceAll("'","''"),typeState);
                if(maps.size()==1){
                    String daId = String.valueOf(maps.get(0).get("ID"));  //档案id
                    String mj = String.valueOf(maps.get(0).get("MJ"));  //档案mj
                    String uploadType = "1";
                    if(StringUtils.isNotEmpty(fileType)) uploadType = fileType;   //文件类型
                    TenantYqdaDocument document = new TenantYqdaDocument();
                    document.setConTableId(Long.valueOf(daId));
                    document.setTableName(tenantCategory.getEfileTableName());
                    String orderNoStr = documentMapper.MaxOrderNo(document);
                    Integer orderNo =  StringUtils.isEmpty(orderNoStr) ? 1:(Integer.valueOf(orderNoStr)+1);
                    String savefilePath = FileUploadUtils.extractPath(tenantCategory,Long.valueOf(daId));  //文件路径
                    String savefileName = extractFilename(Integer.valueOf(uploadType),Long.valueOf(daId),orderNo,ext);  //保存文件名

                    //创建文件夹
                    File file = new File(uplodPath + savefilePath);
                    if(!file.exists()){
                        file.mkdirs();
                    }
                    //fileName = fileName.replaceAll("'","''");
                    String fileCountSql = "select count(1) from "+tenantCategory.getEfileTableName()+" where type = "+uploadType+" and " +
                            "con_table_id = "+daId+" and doc_name = '"+fileName.replaceAll("'","''")+"' and is_del = 0 ";
                    String fileCount = yqdaarticulatedMapper.getSingle(fileCountSql);
                    if(Integer.parseInt(fileCount)>0){  //存在相同文件
                        String realDocNameSql = "select real_doc_name from "+tenantCategory.getEfileTableName()+" where type = "+uploadType+" and " +
                                "con_table_id = "+daId+" and doc_name = '"+fileName.replaceAll("'","''")+"' and is_del = 0 ";
                        String realDocName = yqdaarticulatedMapper.getSingle(realDocNameSql);
                        savefileName = realDocName;
                    }

                    boolean flag = true; // 是否插入数据
                    boolean addflag = false;  // 是否追加
                    String absolutePath = uplodPath + savefilePath + savefileName;
                    File destfile = new File(absolutePath);
                    if(destfile.exists()){  //目标路径下存在该文件
                        flag = false;
                        if("1".equals(repateOperationMode)){  //跳过
                            articulateCount.success++;
                            articulateCount.jump++;
                            addArticulatedLog(srcFile.length(),ext,fileName,"跳过",null,articulateId,path,repateOperationMode,articulatedType);
                        }
                        if("2".equals(repateOperationMode)){  //覆盖
                            boolean b = destfile.canWrite();
                            if(!b){
                                //File oldFile = new File(oldFilePath);
                                if (destfile.exists()) {
                                    destfile.delete();
                                }

                                try (FileInputStream fis = new FileInputStream(srcFile);
                                     FileOutputStream fos = new FileOutputStream(destfile)) {
                                    byte[] buffer = new byte[1024];
                                    int bytesRead;
                                    while ((bytesRead = fis.read(buffer)) != -1) {
                                        fos.write(buffer, 0, bytesRead);
                                    }
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }else{
                                FileUtils.copyFile(srcFile,destfile);
                            }
                            articulateCount.success++;
                            articulateCount.cover++;
                            addArticulatedLog(srcFile.length(),ext,fileName,"覆盖",null,articulateId,path,repateOperationMode,articulatedType);
                        }
                        if("3".equals(repateOperationMode)){  //追加
                            flag = true;
                            addflag = true;
                            String fileNameWithOutSuffix = fileName.substring(0,fileName.lastIndexOf("."));
                            String rfileNameWithOutSuffix = savefileName.substring(0,savefileName.lastIndexOf("."));
                            String str = fileNameWithOutSuffix.replaceAll("'", "''");
                            String addCountSql = "select count(1) as fileCount from "+tenantCategory.getEfileTableName()+" where type = "+uploadType+" and " +
                                    //"con_table_id = "+daId+" and SUBSTRING(DOC_NAME,0,"+(databaseId.equalsIgnoreCase(DbIdEnum.HIGHGO.getCode())?fileNameWithOutSuffix.length()+1:fileNameWithOutSuffix.length())+") like '"+fileNameWithOutSuffix.replaceAll("'","''")+".%' " +
                                    "con_table_id = "+daId+" and (DOC_NAME like '"+str+".%' or DOC_NAME like '"+str+"(%).%') " +
                                    " and doc_file_type = '"+ext.toUpperCase()+"' and is_del = 0";
                            Integer addCount = Integer.parseInt(yqdaarticulatedMapper.getSingle(addCountSql));
                            addCount = addCount - 1;
                            fileNameWithOutSuffix = fileNameWithOutSuffix+"("+(addCount+1)+")";
                            rfileNameWithOutSuffix = rfileNameWithOutSuffix+"("+(addCount+1)+")";
                            File addFile = new File(uplodPath + savefilePath + rfileNameWithOutSuffix + "." +ext);
                            FileUtils.copyFile(srcFile, addFile);
                            fileName = fileNameWithOutSuffix + "." +ext;
                            savefileName = rfileNameWithOutSuffix+"."+ext;
                            articulateCount.add++;
                        }
                    }else{
                        FileUtils.copyFile(srcFile,destfile);
                    }
                    if(flag){
                        TenantYqdaDocument doc = new TenantYqdaDocument();
                        Map<String,String> colNum = new HashMap<>();
                        colNum.put("PATH",savefilePath+savefileName);
                        colNum.put("DOC_ORDER",orderNo.toString());
                        colNum.put("DOC_NAME",fileName);
                        colNum.put("DOC_FILE_TYPE",ext.toUpperCase());
                        colNum.put("IS_DEL","0");
                        // 获取文件创建时间
                        Path path2 = Paths.get(uplodPath+savefilePath+savefileName);
                        // 获取文件属性
                        BasicFileAttributes attributes = Files.readAttributes(path2, BasicFileAttributes.class);
                        // 获取文件创建时间
                        FileTime createTime = attributes.creationTime();
                        // 将文件创建时间转换为标准格式
                        String dateFormat = df.format(createTime.toMillis());
                        //logger.info("创建时间：：：{}",dateFormat);
                        colNum.put("ACTION_TIME",dateFormat);
                        colNum.put("CREATE_TIME",DateUtils.getTime());
                        colNum.put("DOC_FILE_SIZE",String.valueOf(srcFile.length()));
                        colNum.put("IS_INDEX","0");
                        colNum.put("TYPE",uploadType);
                        colNum.put("REAL_DOC_NAME",savefileName);
                        colNum.put("DOC_MNT",uplodPath);
                        colNum.put("ARTICULATED_ID",articulateId);
                        colNum.put("TO_OFD","0");
                        if(StringUtils.isNotEmpty(mj) && !"null".equals(mj) && FBswitch){
                            colNum.put("MJ",mj);
                        }
                        colNum.put("FILE_ONLY_VAL", WebServiceFileUtils.getFileMD5(new File(absolutePath)));
                        doc.setColNames(colNum);
                        doc.setTableName(tenantCategory.getEfileTableName());
                        doc.setDocId(SnowflakeIdGenerator.generateId());
                        doc.setConTableId(Long.valueOf(daId));
                        doc.setCreateBy(SecurityUtils.getUsername());
                        int i = documentMapper.insertDocument(doc);
                        //更新件的电子文件数字段
                        yqdaMapper.updateEfileCount(Long.valueOf(daId),"ID",1,tenantCategory.getFileTableName());
                        yqdaMapper.updateEfileCount(Long.valueOf(daId),"DA_ID",1,new TenantYqda().getTableName());

                        if(i>0) articulateCount.success++;
                        else articulateCount.fail++;
                        if(addflag){
                            if(i>0){
                                addArticulatedLog(srcFile.length(),ext,fileName,"追加成功",null,articulateId,path,repateOperationMode,articulatedType);
                            }else{
                                addArticulatedLog(srcFile.length(),ext,fileName,"追加失败","添加文件信息失败",articulateId,path,repateOperationMode,articulatedType);
                            }
                        }else{
                            if(i>0){
                                addArticulatedLog(srcFile.length(),ext,fileName,"挂接成功",null,articulateId,path,repateOperationMode,articulatedType);
                            }else{
                                addArticulatedLog(srcFile.length(),ext,fileName,"挂接失败","添加文件信息失败",articulateId,path,repateOperationMode,articulatedType);
                            }
                        }
                    }

                }else if(maps.size()==0){
                    String str ="";
                    if(null != typeState){
                        if("1".equals(typeState)){
                            str="或未归档";
                        } else if("0".equals(typeState)){
                            str="或未在 数字化成果未接收、档案征集、接收管理菜单";
                        }else if("2".equals(typeState)){
                            str="或未在接收管理菜单";
                        }
                    }
                    addArticulatedLog(srcFile.length(),ext,fileName,"挂接失败","档号"+dh+"不存在"+str,articulateId,path,repateOperationMode,articulatedType);
                    articulateCount.fail++;
                }else if(maps.size()>1){
                    addArticulatedLog(srcFile.length(),ext,fileName,"挂接失败","档号"+dh+"不唯一",articulateId,path,repateOperationMode,articulatedType);
                    articulateCount.fail++;
                }
            }catch (NumberFormatException e){
                e.printStackTrace();
                addArticulatedLog(srcFile.length(),ext,fileName,"挂接失败","字符串转换为数字异常",articulateId,path,repateOperationMode,articulatedType);
                articulateCount.fail++;
            }catch (ArrayIndexOutOfBoundsException e){
                e.printStackTrace();
                addArticulatedLog(srcFile.length(),ext,fileName,"挂接失败","数组下标越界异常",articulateId,path,repateOperationMode,articulatedType);
                articulateCount.fail++;
            }catch(NullPointerException e){
                e.printStackTrace();
                addArticulatedLog(srcFile.length(),ext,fileName,"挂接失败","空指针异常",articulateId,path,repateOperationMode,articulatedType);
                articulateCount.fail++;
            }catch(Exception e){
                e.printStackTrace();
                addArticulatedLog(srcFile.length(),ext,fileName,"挂接失败",e.getMessage(),articulateId,path,repateOperationMode,articulatedType);
                articulateCount.fail++;
            }
        }
    }

    public void addArticulatedLog(Long docFileSize,String docFileType,String docName,
                                  String result,String failResult,String id,String path,String mode,String artiMode){
        if("server".equals(artiMode)){
            YqdaarticulatedServerLog serverLog = new YqdaarticulatedServerLog();
            serverLog.setArticulatedId(Long.valueOf(id));
            serverLog.setDocFileSize(String.valueOf(docFileSize));
            serverLog.setDocName(docName);
            serverLog.setResult(result);
            serverLog.setRepeatOperMode(mode);
            serverLog.setFailResult(failResult);
            serverLog.setPath(path);
            yqdaarticulatedMapper.insertBjyqYqdaarticulatedServerLog(serverLog);
        }else{
            YqdaarticulatedLog log = new YqdaarticulatedLog();
            log.setDocFileSize(String.valueOf(docFileSize));
            log.setDocFileType(docFileType);
            log.setDocName(docName);
            log.setResult(result);
            log.setFailResult(failResult);
            log.setArticulatedId(Long.valueOf(id));
            yqdaarticulatedMapper.insertBjyqYqdaarticulatedLog(log);
        }
    }


    public String getDHByLevel(TenantCategory tenantCategory, String ruleId, String archivelCode){
        String dh = "";
        Integer type = tenantCategory.getType();
        String vtetype = 0==type?"f":1==type||3==type?"v":"";
        TenantCodeList tenantCodeList = new TenantCodeList();
        String tableName = tenantCodeList.getTableName();
        List<String> gdz = tenantCodeListMapper.selectNodeValByIdAndTypeGd(Long.valueOf(ruleId), vtetype, tableName);
        String jianlianjie = "";// 原规则件的连接符
        if("v".equals(vtetype)){
            List<String> fgdz = tenantCodeListMapper.selectNodeValByIdAndTypeGd(Long.valueOf(ruleId), "f", tableName);
            jianlianjie = fgdz.get(0);
        }
        String[] split = archivelCode.split(",,,");
        if("f".equals(vtetype)){
            for(int s=0;s<split.length-1;s++){
                if(s == split.length-2){
                    dh +=split[s];
                }else{
                    dh +=split[s]+gdz.get(s);
                }
            }
        }else{
            for(int s=0;s<split.length-1;s++){
                if(s == split.length-2){
                    dh += jianlianjie+split[s];
                }else if(s == split.length-3){
                    dh +=split[s];
                }else{
                    dh +=split[s]+gdz.get(s);
                }
            }
        }
        return dh;
    }

    public static final String extractFilename(Integer type , Long daId, Integer orderNo, String ext)
    {
        String fileName = daId+"0"+type+"A"+ (orderNo<999 ? (orderNo<99 ? (orderNo<9 ? "00"+orderNo:("0"+orderNo)):orderNo):orderNo);
        StringBuilder path = new StringBuilder().append(fileName).append(".").append(ext);
        return path.toString();
    }

    public List<Map<String,Object>> hasArchive(String tableName,String dhColumn,String dh,String type){
        String state = "2,3,4,5";
        if(null != type){
            if("1".equals(type)){
                state = "5";
            } else if("0".equals(type)){
                state = "3,11,12";
            }else if("2".equals(type)){
                state = "12";
            }
        }
        String sql = "select id,mj from "+tableName+" where "+dhColumn+" = '"+dh+"' and is_del=0 and state in ("+state+")";
        List<Map<String, Object>> maps = yqdaarticulatedMapper.executeSql(sql);
        return maps;
    }

    /**
     * 新增挂接
     *
     * @param bjyqYqdaarticulated 挂接
     * @return 结果
     */
    @Override
    public int insertBjyqYqdaarticulated(Yqdaarticulated bjyqYqdaarticulated)
    {
        return yqdaarticulatedMapper.insertBjyqYqdaarticulated(bjyqYqdaarticulated);
    }

    /**
     * 修改挂接
     *
     * @param bjyqYqdaarticulated 挂接
     * @return 结果
     */
    @Override
    public int updateBjyqYqdaarticulated(Yqdaarticulated bjyqYqdaarticulated)
    {
        return yqdaarticulatedMapper.updateBjyqYqdaarticulated(bjyqYqdaarticulated);
    }

    /**
     * 批量删除挂接
     *
     * @param IDs 需要删除的挂接主键
     * @return 结果
     */
    @Override
    public int deleteBjyqYqdaarticulatedByIDs(String[] IDs)
    {
        return yqdaarticulatedMapper.deleteBjyqYqdaarticulatedByIDs(IDs);
    }

    /**
     * 删除挂接信息
     *
     * @param ID 挂接主键
     * @return 结果
     */
    @Override
    public int deleteBjyqYqdaarticulatedByID(String ID)
    {
        return yqdaarticulatedMapper.deleteBjyqYqdaarticulatedByID(ID);
    }

}
